package com.abso.mp3tunes.locker.ui.actions;

import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Shell;

import com.abso.mp3tunes.locker.core.LockerServiceException;
import com.abso.mp3tunes.locker.core.data.Playlist;
import com.abso.mp3tunes.locker.core.data.Track;
import com.abso.mp3tunes.locker.ui.LockerImages;
import com.abso.mp3tunes.locker.ui.LockerPlugin;
import com.abso.mp3tunes.locker.ui.viewers.LockerViewer;
import com.abso.mp3tunes.locker.ui.views.LockerBrowserView;

/**
 * Action able to remove a set of tracks from their playlists.
 */
public class RemoveFromPlaylistsAction extends AbstractLockerViewerAction {

	/**
	 * A list of object arrays. Each array is composed by a playlist and a
	 * track.
	 */
	private List playlistsAndTracks;

	/**
	 * Constructs a new action.
	 * 
	 * @param lockerViewer
	 *            the Locker tree viewer.
	 */
	public RemoveFromPlaylistsAction(LockerViewer lockerViewer) {
		super("Remove from Playlist", LockerImages
				.getDescriptor(LockerImages.REMOVE_FROM_PLAYLIST), lockerViewer);
	}

	/**
	 * Sets the list playlists and associated tracks.
	 * 
	 * @param playlistsAndTracks
	 *            a list of object arrays; each array is composed by a playlist
	 *            and a track.
	 */
	public void setPlaylistsAndTracks(List playlistsAndTracks) {
		this.playlistsAndTracks = playlistsAndTracks;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.action.Action#run()
	 */
	public void run() {
		Shell shell = LockerPlugin.getActiveWorkbenchShell();
		if (!MessageDialog.openQuestion(shell, "Confirm Removal",
				"Are you sure you want to remove the selected "
						+ ((playlistsAndTracks.size() > 1) ? "tracks?"
								: "track?"))) {
			return;
		}
		IRunnableWithProgress runnable = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
					throws InvocationTargetException, InterruptedException {
				monitor.beginTask("Removing tracks", playlistsAndTracks.size());
				try {
					for (Iterator i = playlistsAndTracks.iterator(); i
							.hasNext();) {
						if (monitor.isCanceled()) {
							break;
						}
						Object[] playlistAndTrack = (Object[]) i.next();
						Playlist playlist = (Playlist) playlistAndTrack[0];
						Track track = (Track) playlistAndTrack[1];
						monitor.subTask(getTrackLabel(track));
						LockerPlugin.getDefault().getLockerService()
								.removeTrackFromPlaylist(playlist.getId(),
										track.getFileKey());
						monitor.worked(1);
					}
					getLockerViewer().getLockerBrowser().setViewerDirty(
							LockerBrowserView.PLAYLIST_MODE);
				} catch (final LockerServiceException e) {
					showErrorDialog("Error", "Unable to update the playlist",
							"Error updating the playlist", e);
				} finally {
					monitor.done();
				}
				runUIAsync(new Runnable() {
					public void run() {
						getLockerViewer().setDirty();
						getLockerViewer().updateContent();
					}
				});
			}
		};
		try {
			ProgressMonitorDialog dialog = new ProgressMonitorDialog(
					LockerPlugin.getActiveWorkbenchShell()) {
				protected void configureShell(final Shell shell) {
					super.configureShell(shell);
					shell.setText("Track Removal");
				}
			};
			dialog.run(true, true, runnable);
		} catch (InvocationTargetException e) {
		} catch (InterruptedException e) {
		}
	}
}
